Message Authentication Codes (MACs) can be used to authenticate data or messages communicated between two electronic devices, such as electronic control units (ECUs). To ensure that the data transmitted to an ECU is authentic, a MAC can be generated by a sending ECU using a MAC algorithm, which is a function of the data to be sent and a secret key. Example MAC algorithms include HMAC, a hash function-based message authentication algorithm, and CMAC, a block cipher-based message authentication algorithm. When used to authenticate communication between ECUs, the data is sent to a receiving ECU along with the generated MAC. The receiving ECU has its own copy of the secret key and MAC algorithm, which the receiving ECU can use to calculate a comparison MAC using the received data, its own copy of the secret key and the MAC algorithm. When the comparison MAC calculated by the receiving ECU matches the MAC it was sent, the receiving ECU can determine that the data and/or message is authentic and output a “yes” answer confirming this. In contrast, when the comparison MAC calculated by the receiving ECU does not match the MAC received, a “no” answer can be output. In this sense, the receiving ECU outputs a binary “yes” or “no” response to whether or not the comparison MAC matches the received MAC. The process of determining if the MAC of a message is correct and outputting a binary “yes” or “no” response can be referred to as MAC verification. Although the MAC verification process can calculate the correct MAC (based on the data and the appropriate secret key) it need not expose the correct MAC outside of the verification process. As a consequence, it is possible to define a verification process that would not allow the efficient generation of correct MACs if the secret key is not known to the party requesting the verification of the MAC for a particular message.